package fda.base;

import java.util.LinkedList;
import java.util.List;

/**
 * Structure represent a memory with limited size: <br>
 * case1: 11 blocks * 40 tuples = 440 tuples
 * case2: 102 blocks * 40 tuples = 4080 tuples
 * 
 * use this class as Tuple[] mem = Memory.getInstance().getMemory();  from any class/method
 */
public class Memory {

	private static Memory theInstance = null;

	private final Tuple[] memory;
	private final List<Block> memBlocks;

	private Memory() {
		int tuplesInMemory = Constants.MEMORY_SIZE_BLOCKS * Constants.MAX_TYPLES_IN_BLOCK;
		
		memory = new Tuple[tuplesInMemory];
		memBlocks = new LinkedList<Block>();
		
		List<Tuple> tpl = new LinkedList<Tuple>();;
		for(int i = 0; i < Constants.MEMORY_SIZE_BLOCKS; i++) {
			for(int j = 0; j < (Constants.MAX_TYPLES_IN_BLOCK - 1); j++) {
				tpl.add(memory[j]);
			}
			memBlocks.add(new Block(tpl));
		}
	}

	/**
	 * @return a static array that represent a memory. Use this array to sort and merge
	 */
	public Tuple[] getMemory() {
		return memory;
	}
	
	/**
	 * @return List of blocks of memory (except output block)<br>
	 * Example: if memory has total 11 blocks, the method will returns 10 blocks (1, 2, 3, 4, 5, 6, 7, 8, 9, 10). Block 0 is used as output
	 */
	public List<Block> getMemBlocks() {
		return memBlocks;
	}
	
	/**
	 * @return singleton instance of memory.
	 */
	public static Memory getInstance() {
		if (theInstance == null) {
			theInstance = new Memory();
		}

		return theInstance;
	}
}
